import { Base64 } from 'js-base64'

function createGuid () {
  let d = new Date().getTime()
  return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
    const r = (d + Math.random() * 16) % 16 | 0
    d = Math.floor(d / 16)
    return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16)
  })
}

/*
    guid 唯一标识， 用来 window.JSCallNativeCallBack.callBackCache 记录回调函数
    methodName 调用原生的方法名， 用来给原生区别调用的功能模块
    param 传给原生的参数 string
    successCallBack failedCallBack Flutter通过执行 controller.runJavascript(window.JSCallNativeCallBack.successCallBack(guid, 参数))来回调到js
  // let src = `uniweb://?guid=${guid}&methodName=${methodName}&param=${encodeURIComponent(param)}&successBack=${successCallBack}&errorBack=${failedCallBack}`
*/
function _execute (guid, methodName, param, type, successCallBack, failedCallBack) {
  try {
    if (param && typeof param !== 'string') {
      param = JSON.stringify(param)
    }
  } catch (e) {
    throw new Error(e.toString())
  }
  console.log(param, '传递给App的数据')
  console.log(Base64.encode(param), '传递给App的数据')
  const src = `uniwebview://reader?param=${Base64.encode(param)}&type=${type}`
  window.location.href = src
  // const element = document.createElement('iframe')
  // element.setAttribute('src', src)
  // element.setAttribute('style', 'display:none')
  // document.body.appendChild(element)
  // element.parentNode.removeChild(element)
}

window.JSCallNativeCallBack = {
  callBackCache: {},
  successCallBack: function (guid, data) {
    const res = data ? JSON.parse(data) : {}
    this.callBackCache[guid].successCallBack(res.data)
    delete this.callBackCache[guid]
  },
  failedCallBack: function (guid, data) {
    this.callBackCache[guid].failedCallBack(data)
    delete this.callBackCache[guid]
  }
}

// 原生调用h5
window.nativeCallJs = function (name = 'setAppInfo', data) {
  //此处等待原生发送的消息
  if (window[name] && typeof window[name] === 'function') {
    try {
      const res = data ? JSON.parse(data) : {}
      window[name](res)
    } catch (e) {
      console.log('解析JSON出错', e.toString())
    }
  } else {
    console.log('未找到该方法',name)
  }
}

function JSCallNativeFactory (guid, methodName, param, successCallBack, failedCallBack) {
  if (typeof successCallBack !== 'function' || typeof failedCallBack !== 'function') {
    throw new Error('callback must be a function')
  }
  this.successCallBack = successCallBack
  this.failedCallBack = failedCallBack
  _execute(guid, methodName, param, 'JSCallNativeCallBack.successCallBack', 'JSCallNativeCallBack.failedCallBack')
}

window.JSCallNative = function (name, extraParams) {
  if (!name) {
    console.log('输入方法名')
    return
  }
  extraParams = extraParams || {}
  let param = extraParams.param || ''
  let successCallBack = extraParams.successCallBack || function () {
  }
  let failedCallBack = extraParams.failedCallBack || function (msg) {
    throw new Error(msg)
  }
  let guid = createGuid()

  window.JSCallNativeCallBack.callBackCache[guid] = new JSCallNativeFactory(guid, name, param,
    successCallBack,
    failedCallBack)
}
export default window.JSCallNative

